#ifndef _H_LIBLUI_
#define _H_LIBLUI_

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <math.h>
#include <unistd.h>
#include <fcntl.h>
#include <inttypes.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fb.h>
#include <linux/input.h>
#include <termios.h>
#include <wchar.h>
#include <locale.h>
#include <time.h>
#include <wchar.h>

#include "list.h"
#include "rbtree.h"

#define list_is_end_for_each(_p_node_,_head_,_member_)	( & ((_p_node_)->_member_) == (_head_) )

#include "libbmp.h"

/*
 * Util
 */

#ifndef MAX
#define MAX(_a_,_b_) ((_a_)>(_b_)?(_a_):(_b_))
#endif

#ifndef MAX3
#define MAX3(_a_,_b_,_c_) ((_a_)>(_b_)?((_a_)>(_c_)?(_a_):(_c_)):((_b_)>(_c_)?(_b_):(_c_)))
#endif

#ifndef MIN
#define MIN(_a_,_b_) ((_a_)<(_b_)?(_a_):(_b_))
#endif

#ifndef STRCMP                  
#define STRCMP(_a_,_C_,_b_)		( strcmp(_a_,_b_) _C_ 0 )
#define STRNCMP(_a_,_C_,_b_,_n_)	( strncmp(_a_,_b_,_n_) _C_ 0 )
#endif

#ifndef STRICMP
#define STRICMP(_a_,_C_,_b_)		( strcasecmp(_a_,_b_) _C_ 0 )
#define STRNICMP(_a_,_C_,_b_,_n_)	( strncasecmp(_a_,_b_,_n_) _C_ 0 )
#endif

#ifndef MEMCMP
#define MEMCMP(_a_,_C_,_b_,_n_) ( memcmp(_a_,_b_,_n_) _C_ 0 )
#endif

#define PROPERTIES_ADD(_properties_,_add_)		{ (_properties_) |= (_add_) ; }
#define PROPERTIES_REMOVE(_properties_,_remove_)	{ (_properties_) &= ~(_remove_) ; }

#define ADD_PROPERTY(_properties_,_add_)		( (_properties_) | (_add_) )
#define REMOVE_PROPERTY(_properties_,_remove_)		( (_properties_) & ~(_remove_) )
#define TEST_PROPERTY(_properties_,_test_)		( ((_properties_)&(_test_)) == (_test_) )

#define BETWEEN_IN_INT(_min_,_val_,_max_)		( (_min_)<=(_val_) && (_val_)<=(_max_) )
#define OUTSIDE_OF_INT(_min_,_val_,_max_)		( (_val_)<(_min_) || (_max_)<(_val_) )

/*
 * External Structures
 */

struct LUIWindowsManager ;
struct LUIWindow ;
struct LUIControl ;

/*
 * Basic Structures
 */

struct LUIPoint
{
	int	x ;
	int	y ;
} ;

struct LUISize
{
	int	width ;
	int	height ;
} ;

struct LUIRectangle
{
	int	left ;
	int	top ;
	int	width ;
	int	height ;
} ;

struct LUIRectangle LUIRectangle( int left , int top , int width , int height );

struct LUIRelativePosition
{
	int	relative_left ;
	int	relative_top ;
} ;
/*
 * Event
 */

#define LUIDEVICE_KEYBORAD		1

#define LUIEVENT_KEY_OVER			11
#define LUIEVENT_KEY_DOWN			12
#define LUIEVENT_KEY_UP				13

#define LUIDEVICE_MOUSE			2

#define LUIEVENT_MOUSE_OVER			21
#define LUIEVENT_MOUSE_DOWN			22
#define LUIEVENT_MOUSE_UP			23
#define LUIEVENT_MOUSE_IN			24
#define LUIEVENT_MOUSE_OUT			25

#define LUICODE_LEFT					1
#define LUICODE_RIGHT					2
#define LUICODE_MIDDLE					3

#define LUIDEVICE_WINDOW		10

#define LUIEVENT_WINDOW_CREATE			101
#define LUIEVENT_WINDOW_DESTROY			102

#define LUIEVENT_WINDOW_ACTIVE			111
#define LUIEVENT_WINDOW_INACTIVE		112

#define LUIEVENT_WINDOW_RESIZE			121
#define LUIEVENT_WINDOW_MOVE			122

#define LUIEVENT_WINDOW_CLOSE			131
#define LUIEVENT_WINDOW_MAXIMIZE		132
#define LUIEVENT_WINDOW_RESTORE			133
#define LUIEVENT_WINDOW_MINIMIZE		134

#define LUIDEVICE_CONTROL		20

#define LUIEVENT_CONTROL_BUTTON_PRESS		1101
#define LUIEVENT_CONTROL_BUTTON_UNPRESS		1102

struct LUIEvent
{
	struct LUIWindow	*window ;
	struct LUIControl	*control ;
	
	struct timeval		timestamp ;
	
	int			device ;
	int			event ;
	int			code ;
	struct LUIPoint		cursor_pos ;
	
	union
	{
		struct LUIRectangle	relative_offset ;
		struct LUIRectangle	window_rect ;
	} data ;
	
	struct list_head	this_listnode ;
} ;

struct LUIEvent *LUIAllocMessage( struct LUIWindowsManager *windows_manager , struct LUIWindow *window , struct LUIControl *control );
int LUISendMessage( struct LUIWindowsManager *windows_manager , struct LUIWindow *window , struct LUIControl *control , int deivce , int _event , int code );
int LUISendMessageEx( struct LUIWindowsManager *windows_manager , struct LUIEvent *event );

/*
 * Mouse Cursor
 */

int LUIGetMouseCursor( struct LUIWindowsManager *windows_manager );
void LUISetMouseCursor( struct LUIWindowsManager *windows_manager , int mouse_cursor_type );

/*
 * LUIControl
 */

#define LUICONTROL_TYPE_CUSTOM_BASE		10000

#define LUICONTROL_STYLE_EDGE			1
#define LUICONTROL_STYLE_TEXTALIGN_LEFT		128
#define LUICONTROL_STYLE_TEXTALIGN_MIDDLE	256
#define LUICONTROL_STYLE_TEXTALIGN_RIGHT	512

#define LUICONTROL_STYLE_CUSTOM_BASE		1024

#define LUICONTROL_STYLES_DEFAULT		(LUICONTROL_STYLE_EDGE)

#define LUICONTROL_PROPERTY_ENABLE		1
#define LUICONTROL_PROPERTY_SHOW		2
#define LUICONTROL_PROPERTY_CUSTOM_BASE		1024

#define LUICONTROL_PROPERTIES_DEFAULT		(LUICONTROL_PROPERTY_ENABLE|LUICONTROL_PROPERTY_SHOW)

#define LUICONTROL_BORDER_WITDH_DEFAULT		1

typedef void funcLUIDrawControlProc( struct LUIControl *control );
typedef int funcLUIControlEventProc( struct LUIControl *control , struct LUIEvent *event );

struct LUIControl *LUICreateControl( struct LUIWindow *window , struct LUIRectangle control_relative_rect , int styles , int properties , int control_type , void *data , funcLUIDrawControlProc *pfuncLUIDrawControlProc );
int LUIDestroyControl( struct LUIControl *control );

void LUISetControlBgColor( struct LUIControl *control , struct RBGA *p_color );
void LUISetControlFontColor( struct LUIControl *control , struct RBGA *p_color );

int LUIGetControlStyles( struct LUIControl *control );
int LUIGetControlProperties( struct LUIControl *control );

int LUIGetControlType( struct LUIControl *control );
void LUISetControlData( struct LUIControl *control , void *data );
void *LUIGetControlData( struct LUIControl *control );

struct LUIWindow *LUIGetWindowOfControl( struct LUIControl *control );

void LUISetDrawControlProc( struct LUIControl *control , funcLUIDrawControlProc *pfuncLUIDrawControlProc );
void LUISetControlEventProc( struct LUIControl *control , funcLUIControlEventProc *pfuncLUIControlEventProc );

/*
 * LUIButtonControl
 */

#define LUIBUTTON_WIDTH_DEFAULT			80
#define LUIBUTTON_HEIGHT_DEFAULT		22

#define LUIBUTTON_STYLES_DEFAULT		(LUICONTROL_STYLES_DEFAULT|LUICONTROL_STYLE_TEXTALIGN_MIDDLE)

#define LUIBUTTON_PROPERTY_TOGGLE		LUICONTROL_PROPERTY_CUSTOM_BASE

#define LUIBUTTON_PROPERTIES_DEFAULT		(LUICONTROL_PROPERTIES_DEFAULT)

struct LUIControl *LUICreateButtonControl( struct LUIWindow *window , struct LUIRectangle control_relative_rect , int styles , int properties , wchar_t *caption_text );
int LUIDestroyButtonControl( struct LUIControl *control );

int LUIIsButtonPress( struct LUIControl *control );
void LUISetButtonPress( struct LUIControl *control );
void LUISetButtonUnpress( struct LUIControl *control );
void LUISetButtonControlData( struct LUIControl *control , void *data );
void *LUIGetButtonControlData( struct LUIControl *control );

typedef int funcLUIOnButtonClickProc( struct LUIControl *control );
void LUISetOnButtonClickProc( struct LUIControl *control , funcLUIOnButtonClickProc *pfuncLUIOnButtonClickProc );

/*
 * LUILabelControl
 */

#define LUILABEL_STYLES_DEFAULT		(0)

#define LUILABEL_PROPERTIES_DEFAULT	(LUICONTROL_PROPERTIES_DEFAULT)

struct LUIControl *LUICreateLabelControl( struct LUIWindow *window , struct LUIRectangle control_rect , int styles , int properties , wchar_t *label_text );
int LUIDestroyLabelControl( struct LUIControl *control );


/*
 * LUIWindow
 */

#define LUIWINDOW_STYLE_NONE			0
#define LUIWINDOW_STYLE_BORDER			1
#define LUIWINDOW_STYLE_TITLEBAR		2
#define LUIWINDOW_STYLE_MINIMIZE_BUTTONBOX	4
#define LUIWINDOW_STYLE_MAXIMIZE_BUTTONBOX	8
#define LUIWINDOW_STYLE_QUIT_BUTTONBOX		16

#define LUIWINDOW_STYLES_DEFAULT	(LUIWINDOW_STYLE_TITLEBAR|LUIWINDOW_STYLE_BORDER|LUIWINDOW_STYLE_MINIMIZE_BUTTONBOX|LUIWINDOW_STYLE_MAXIMIZE_BUTTONBOX|LUIWINDOW_STYLE_QUIT_BUTTONBOX)

#define LUIWINDOW_PROPERTY_NONE			0
#define LUIWINDOW_PROPERTY_ENABLE		1
#define LUIWINDOW_PROPERTY_SHOW			2
#define LUIWINDOW_PROPERTY_MOVE_ENABLE		4
#define LUIWINDOW_PROPERTY_RESIZE_ENABLE	8
#define LUIWINDOW_PROPERTY_MINIMIZE		16
#define LUIWINDOW_PROPERTY_MAXIMIZE		32
#define LUIWINDOW_PROPERTY_MODAL		64

#define LUIWINDOW_PROPERTIES_DEFAULT	(LUIWINDOW_PROPERTY_ENABLE|LUIWINDOW_PROPERTY_SHOW|LUIWINDOW_PROPERTY_MOVE_ENABLE|LUIWINDOW_PROPERTY_RESIZE_ENABLE)

#define LUIWINDOW_RETURNCODE_NONE		0
#define LUIWINDOW_RETURNCODE_QUIT		1
#define LUIWINDOW_RETURNCODE_OK			2
#define LUIWINDOW_RETURNCODE_CANCEL		3
#define LUIWINDOW_RETURNCODE_YES		4
#define LUIWINDOW_RETURNCODE_NO			5

typedef void funcLUIDrawWindowProc( struct LUIWindow *window );
typedef int funcLUIWindowEventProc( struct LUIWindow *window , struct LUIEvent *event );

struct LUIWindow *LUICreateWindow( struct LUIWindowsManager *windows_manager , struct LUIWindow *parent_window , struct LUIRectangle window_rect , wchar_t *titlebar_text , int styles , int properties );
int LUIDestroyWindow( struct LUIWindow *window );

void LUISetWindowClientBgColor( struct LUIWindow *window , struct RBGA *p_color );

void LUIShowWindow( struct LUIWindow *window );
void LUIHideWindow( struct LUIWindow *window );
void LUIActiveWindow( struct LUIWindow *window );
void LUIInactiveWindow( struct LUIWindow *window );
void LUICloseWindow( struct LUIWindow *window );
void LUIMinimizeWindow( struct LUIWindow *window );
void LUIMaximizeWindow( struct LUIWindow *window );
void LUIRestoreWindow( struct LUIWindow *window );

void LUISetWindowEventProc( struct LUIWindow *window , funcLUIWindowEventProc *pfuncLUIWindowEventProc );

int LUIGetWindowStyles( struct LUIWindow *window );
int LUIGetWindowProperties( struct LUIWindow *window );

int LUIGetWindowReturnCode( struct LUIWindow *window );
void LUISetWindowReturnCode( struct LUIWindow *window , int return_code );
struct LUIWindowsManager *LUIGetWindowsManagerOfWindow( struct LUIWindow *window );

/*
 * LUIWindowsManager
 */

struct LUIWindowsManager *LUICreateWindowsManager();
void LUIDestroyWindowsManager( struct LUIWindowsManager *windows_manager );

int LUIWindowsManagerLoop( struct LUIWindowsManager *windows_manager );

int LUILoadWallpaper( struct LUIWindowsManager *windows_manager , char *wallpaper_pathfilename_format , ... );

/*
 * LUIMessageBox
 */

#define LUIMESSAGEBOX_STYLES_DEFAULT		(LUIWINDOW_STYLE_TITLEBAR|LUIWINDOW_STYLE_BORDER)

#define LUIMESSAGEBOX_PROPERTIES_DEFAULT	(LUIWINDOW_PROPERTY_ENABLE|LUIWINDOW_PROPERTY_SHOW|LUIWINDOW_PROPERTY_MOVE_ENABLE|LUIWINDOW_PROPERTY_MODAL)

#define LUIMESSAGEBOX_BUTTON_OK		1
#define LUIMESSAGEBOX_BUTTON_CANCEL	2
#define LUIMESSAGEBOX_BUTTON_YES	4
#define LUIMESSAGEBOX_BUTTON_NO		8

int LUIMessageBox( struct LUIWindowsManager *windows_manager , struct LUIWindow *parent_window , int styles , int properties , int buttons , wchar_t *title_text , wchar_t *message_text_format , ... );





#endif

